package com.kamistoat.meimeichat.meimeichatserverapplication.netty.handlers;

import com.alibaba.fastjson.JSON;
import com.kamistoat.meimeichat.meimeichatserverapplication.common.utils.R;
import com.kamistoat.meimeichat.meimeichatserverapplication.entity.MmcChatRecordEntity;
import com.kamistoat.meimeichat.meimeichatserverapplication.entity.MmcUserEntity;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.NettyServerBizHandler;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.service.NettyUserService;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.utils.NettyConstants;
import com.kamistoat.meimeichat.meimeichatserverapplication.netty.utils.NettySocketChannelUtil;
import com.kamistoat.meimeichatserveraggrement.protocol.login.dto.ChatRecordDto;
import com.kamistoat.meimeichatserveraggrement.protocol.login.dto.UserFriendDto;
import com.kamistoat.meimeichatserveraggrement.protocol.talk.TalkNoticeRequest;
import com.kamistoat.meimeichatserveraggrement.protocol.talk.TalkNoticeResponse;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

/**
 * 创建对话框
 * 当一个用户A在之前没有建立对话框的基础上创建与用户B的新对话框，则在数据库中添加A->B的对话框。注意并不添加B->A的对话框，只有在A真正发送消息时才创建B->A的对话框
 * 该步骤将在发送消息前执行。相当于QQ点开一个对话框，但是不一定就真的要发消息。但是要发消息，肯定得先点开对话框
 * 同时在这里查询AB之间的聊天记录，返回给A用于填充聊天框
 */
@Component
@ChannelHandler.Sharable
public class TalkNoticeHandlerServer extends NettyServerBizHandler<TalkNoticeRequest> {
    @Autowired
    NettyUserService nettyUserService;

    /**
     * @param channel
     * @param talkNoticeRequest
     * @Warning:子类只需要重写该方法
     */
    @Override
    public void channelRead(Channel channel, TalkNoticeRequest talkNoticeRequest) {
        if (talkNoticeRequest == null) return;
        logger.info("新建聊天请求处理: " + JSON.toJSONString(talkNoticeRequest));
        switch (talkNoticeRequest.getTalkType()) {
            // 私聊
            case 0:
                // 添加 自己-好友 的对话框
                CompletableFuture<Void> appendTalkBoxSelf =
                        nettyUserService.asyncAppendTalkBox(talkNoticeRequest.getUserId(), talkNoticeRequest.getFriendUserId(), NettyConstants.TalkType.Friend.getCode());

                List<ChatRecordDto> friendChatRecordDtoList = new ArrayList<>();
                List<MmcChatRecordEntity> friendChatRecordEntities = nettyUserService.queryUserFriendChatRecord(talkNoticeRequest.getUserId(), talkNoticeRequest.getFriendUserId());
                if (friendChatRecordEntities != null && friendChatRecordEntities.size() > 0) {
                    friendChatRecordDtoList = friendChatRecordEntities.stream()
                            // 对方信息已经提前查到，不需要再查，只保留核心记录信息即可
                            .map(record -> {
                                ChatRecordDto chatRecordDto = new ChatRecordDto();
                                chatRecordDto.setTalkId(talkNoticeRequest.getFriendUserId());
                                chatRecordDto.setMsgType(record.getMsgType());
                                chatRecordDto.setMsgContent(record.getMsgContent());
                                chatRecordDto.setMsgDate(record.getMsgDate());
                                if (record.getUserId().equals(talkNoticeRequest.getUserId())) {
                                    // 自己发送的消息，MsgUserType=0
                                    chatRecordDto.setMsgUserType(NettyConstants.MsgUserType.Myself.getCode());
                                } else {
                                    // 好友发送的消息，MsgUserType=1
                                    chatRecordDto.setMsgUserType(NettyConstants.MsgUserType.Friend.getCode());
                                }
                                return chatRecordDto;
                            })
                            .sorted((o1, o2) -> o2.getMsgDate().compareTo(o1.getMsgDate()))
                            .collect(Collectors.toList());
                }
                try {
                    // 将新建聊天框的响应返回
                    TalkNoticeResponse talkNoticeResponse = new TalkNoticeResponse();
                    talkNoticeResponse.setTalkId(talkNoticeRequest.getFriendUserId());
                    talkNoticeResponse.setChatRecordDtoList(friendChatRecordDtoList);
                    talkNoticeResponse.setTalkType(NettyConstants.TalkType.Friend.getCode());
                    appendTalkBoxSelf.get();
                    channel.writeAndFlush(talkNoticeResponse);
                } catch (ExecutionException | InterruptedException e) {
                    e.printStackTrace();
                }
                break;
            case 1:
                // 添加 自己-群组 的对话框
                CompletableFuture<Void> appendTalkBoxGroup =
                        nettyUserService.asyncAppendTalkBox(talkNoticeRequest.getUserId(), talkNoticeRequest.getFriendUserId(), NettyConstants.TalkType.Group.getCode());
                List<ChatRecordDto> groupChatRecordDtoList = new ArrayList<>();
                List<MmcChatRecordEntity> groupChatRecordEntities = nettyUserService.queryUserGroupChatRecord(talkNoticeRequest.getUserId(), talkNoticeRequest.getFriendUserId());
                if (groupChatRecordEntities != null && groupChatRecordEntities.size() > 0) {
                    groupChatRecordDtoList = groupChatRecordEntities.stream()
                            // 对方信息已经提前查到，不需要再查，只保留核心记录信息即可
                            .map(record -> {
                                ChatRecordDto chatRecordDto = new ChatRecordDto();
                                chatRecordDto.setTalkId(talkNoticeRequest.getFriendUserId());
                                chatRecordDto.setMsgType(record.getMsgType());
                                chatRecordDto.setMsgContent(record.getMsgContent());
                                chatRecordDto.setMsgDate(record.getMsgDate());
                                if (record.getUserId().equals(talkNoticeRequest.getUserId())) {
                                    // 自己发送的消息，MsgUserType=0
                                    chatRecordDto.setMsgUserType(NettyConstants.MsgUserType.Myself.getCode());
                                    chatRecordDto.setSenderId(record.getUserId());
                                } else {
                                    // 群组其他成员发送的消息，MsgUserType=1
                                    chatRecordDto.setMsgUserType(NettyConstants.MsgUserType.Friend.getCode());
                                    chatRecordDto.setSenderId(record.getUserId());
                                    // 不再去管是否可能是好友，直接全部重新查
                                    MmcUserEntity strangerFriend = nettyUserService.queryUserInfo(record.getUserId());
                                    chatRecordDto.setSenderNickName(strangerFriend.getUserNickname());
                                    chatRecordDto.setSenderHead(strangerFriend.getUserHead());
                                }
                                return chatRecordDto;
                            })
                            .sorted((o1, o2) -> o2.getMsgDate().compareTo(o1.getMsgDate()))
                            .collect(Collectors.toList());
                }
                try {
                    // 将新建聊天框的响应返回
                    TalkNoticeResponse talkNoticeResponse = new TalkNoticeResponse();
                    talkNoticeResponse.setTalkId(talkNoticeRequest.getFriendUserId());
                    talkNoticeResponse.setChatRecordDtoList(groupChatRecordDtoList);
                    talkNoticeResponse.setTalkType(NettyConstants.TalkType.Group.getCode());
                    appendTalkBoxGroup.get();
                    channel.writeAndFlush(talkNoticeResponse);
                } catch (InterruptedException | ExecutionException e) {
                    e.printStackTrace();
                }
                break;
            default:
                break;
        }
    }
}
